using System;
using System.Collections.Generic;
using System.Text;
using Castle.ActiveRecord;

namespace DigitalFortress.Entities {
	/// <summary>
	/// User.
	/// </summary>
	[ActiveRecord("DF_User")]
	public partial class UserEntity {

		#region Fields
		private System.Guid _userId;
		private string _userName;
		private Int16 _simultaneousAccess = 1;
		private ApplicationEntity _application;
		private IList<RoleEntity> _role = new List<RoleEntity>();
		private MembershipEntity _membership;
		private System.DateTime createDate;
		private bool isBlocked;
		private DateTime? blockedSince;
		private DateTime? unblockedSince;
		#endregion Fields

		#region Constructors
		/// <summary>
		/// Default constructor.
		/// </summary>
		public UserEntity() {

		}

		/// <summary>
		/// Returns a new entity based in a data contract (gets from data store, then updates 
		/// data with the data contract data).
		/// </summary>
		/// <param name="user">Data Contract instance.</param>
		/// <returns>Returns the entity from the data store.</returns>
		public static UserEntity FromContract(User user) {
			UserEntity entity = ActiveRecordMediator<UserEntity>.FindByPrimaryKey(user.UserId);

			entity.SimultaneousAccess = user.SimultaneousAccess;
			if (user.Membership != null) {
				entity.Membership.Description = user.Membership.Description;
				entity.Membership.Email = user.Membership.Email;
			}
			
			return entity;
		}

		/// <summary>
		/// Returns a data contract instance based in this entity.
		/// </summary>
		/// <returns>Returns the data contract instance.</returns>
		public User ToContract() {
			User dc = new User();
			dc.Application = this.Application.ToContract();
			dc.BlockedSince = this.BlockedSince;
			dc.CreateDate = this.CreateDate;
			dc.IsBlocked = this.IsBlocked;
			dc.Membership = new Membership();
			dc.Membership.Description = this.Membership.Description;
			dc.Membership.Email = this.Membership.Email;
			dc.Membership.LastLoginDate = this.Membership.LastLoginDate;
			dc.Membership.User = dc;
			dc.Membership.UserId = this.Membership.UserId;
			dc.SimultaneousAccess = this.SimultaneousAccess;
			dc.UnblockedSince = this.UnblockedSince;
			dc.UserId = this.UserId;
			dc.UserName = this.UserName;

			return dc;
		}
		#endregion Constructors

		#region Properties
		/// <summary>
		/// UserId Property Name.
		/// </summary>
		public const string UserIdProperty = "UserId";
		/// <summary>
		/// User Id.
		/// </summary>
		[PrimaryKey(PrimaryKeyType.Guid)]
		public System.Guid UserId {
			get {
				return this._userId;
			}
			set {
				this._userId = value;
			}
		}

		/// <summary>
		/// User name property name.
		/// </summary>
		public const string UserNameProperty = "UserName";
		/// <summary>
		/// User name.
		/// </summary>
		[Property(ColumnType = "String", Length = 255, NotNull = true)]
		public string UserName {
			get {
				return this._userName;
			}
			set {
				this._userName = value;
			}
		}

		/// <summary>
		/// SimultaneousAccess property name.
		/// </summary>
		public const string SimultaneousAccessProperty = "SimultaneousAccess";
		/// <summary>
		/// How many simultaneous sessions this user is allowed. Defaults to 1.
		/// If this is set to 0, the user may connect as many times as he desires.
		/// </summary>
		[Property(ColumnType = "Int16")]
		public Int16 SimultaneousAccess {
			get {
				return this._simultaneousAccess;
			}
			set {
				this._simultaneousAccess = value;
			}
		}

		/// <summary>
		/// Application property name.
		/// </summary>
		public const string ApplicationProperty = "Application";
		/// <summary>
		/// Application that this user belongs to.
		/// </summary>
		[BelongsTo("ApplicationId", NotNull = true)]
		public ApplicationEntity Application {
			get {
				return this._application;
			}
			set {
				this._application = value;
			}
		}

		/// <summary>
		/// Roles property name.
		/// </summary>
		public const string RolesProperty = "Roles";
		/// <summary>
		/// Roles that this user has.
		/// </summary>
		[HasAndBelongsToMany(typeof(RoleEntity), ColumnRef = "UserId", ColumnKey = "RoleId",
								Table = "DF_UserRoles", Cascade = ManyRelationCascadeEnum.SaveUpdate, Lazy = true)]
		public virtual IList<RoleEntity> Roles {
			get {
				return this._role;
			}
			set {
				this._role = value;
			}
		}

		/// <summary>
		/// Membership property name.
		/// </summary>
		public const string MembershipProperty = "Membership";
		/// <summary>
		/// Membership of this user.
		/// </summary>
		[OneToOne(Cascade = CascadeEnum.SaveUpdate)]
		public MembershipEntity Membership {
			get {
				return this._membership;
			}
			set {
				this._membership = value;
			}
		}

		/// <summary>
		/// CreatedDate Property Name.
		/// </summary>
		public const string CreateDateProperty = "CreatedDate";
		/// <summary>
		/// Date that this user was created.
		/// </summary>
		[Property]
		public System.DateTime CreateDate {
			get {
				return createDate;
			}
			set {
				createDate = value;
			}
		}

		/// <summary>
		/// IsBlocked Property Name.
		/// </summary>
		public const string IsBlockedProperty = "IsBlocked";
		/// <summary>
		/// Indicates whether this user is blocked or not. This value is false when the
		/// user is created.
		/// </summary>
		[Property]
		public bool IsBlocked {
			get {
				return isBlocked;
			}
			set {
				isBlocked = value;
			}
		}

		/// <summary>
		/// BlockedSince Property Name.
		/// </summary>
		public const string BlockedSinceProperty = "BlockedSince";
		/// <summary>
		/// If the user is blocked, indicates when was the blocking date for this user.
		/// Otherwise this is null.
		/// This value defaults to null.
		/// </summary>
		[Property]
		public DateTime? BlockedSince {
			get {
				return blockedSince;
			}
			set {
				blockedSince = value;
			}
		}

		/// <summary>
		/// UnblockedSince Property Name.
		/// </summary>
		public const string UnblockedSinceProperty = "UnblockedSince";
		/// <summary>
		/// If the user is unblocked, indicates when was the unblocking date for this user.
		/// Otherwise this is null.
		/// This value defaults to the CreateDate.
		/// </summary>
		[Property]
		public DateTime? UnblockedSince {
			get {
				return unblockedSince;
			}
			set {
				unblockedSince = value;
			}
		}

		#endregion Properties

	}
}
